package interlocking.core;

import interlocking.model.*;

import javax.swing.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class InterlockingCore {
    private Map<String, Switch> switches;
    private Map<String, Signal> signals;
    private Map<String, TrackCircuit> trackCircuits;
    private final Map<String,Route> routes;
    private final Map<String,Train> trains;


    public InterlockingCore() {
        this.switches = new HashMap<>();
        this.signals = new HashMap<>();
        this.trackCircuits = new HashMap<>();
        this.routes = new HashMap<>();
        this.trains=new HashMap<>();

        initializeStation();
    }

    private void initializeStation() {

        switches.put("SW1", new Switch("SW1",200,300));
        switches.put("SW2", new Switch("SW2",250,300));
        switches.put("SW3", new Switch("SW3",500,300));
        switches.put("SW4", new Switch("SW4",550,300));

        signals.put("S1", new Signal("S1",300,250));
        signals.put("S2", new Signal("S2",400,250));

        signals.put("S3", new Signal("S3",300,300));
        signals.put("S4", new Signal("S1",400,300));

        signals.put("S5", new Signal("S5",350,350));
        signals.put("S6", new Signal("S6",450,350));

        signals.put("P1", new Signal("P1",150,300));
        signals.put("P2", new Signal("P2",600,300));



        trackCircuits.put("T1", new TrackCircuit("T1", "Section1",5,true,350,250));
        trackCircuits.put("T2", new TrackCircuit("T2", "Section2",5,false,350,300));
        trackCircuits.put("T3", new TrackCircuit("T3","Section3",5,false,400,350));

        trains.put("train1",new Train(100,300,5,10));

        routes.put("Route1",new Route("Route1","P1",switches,trackCircuits, Route.RouteType.TRAIN));
        routes.put("Route2",new Route("Route2","P1",switches,trackCircuits, Route.RouteType.TRAIN));
        routes.put("Route3",new Route("Route3","P1",switches,trackCircuits, Route.RouteType.TRAIN));

    }

    public boolean setSwitchPosition(String switchId, Switch.SwitchPosition position) {
        Switch sw = switches.get(switchId);
        if (sw != null && !sw.isLocked() && !sw.isBlocked()) {
            sw.setPosition(position);
            return true;
        }
        return false;
    }

    public Map<String,Route> getRoute(){
        return routes;
    }



    public boolean lockSwitch(String switchId) {
        Switch sw = switches.get(switchId);
        if (sw != null && !sw.isBlocked()) {
            sw.setLocked(true);
            return true;
        }
        return false;
    }

    public boolean setSignalAspect(String signalId, Signal.SignalAspect aspect) {
        Signal signal = signals.get(signalId);
        if (signal != null) {
            signal.setAspect(aspect);
            return true;
        }
        return false;
    }

    public boolean setTrackCircuitOccupied(String trackId, boolean occupied) {
        TrackCircuit tc = trackCircuits.get(trackId);
        if (tc != null) {
            tc.setOccupied(occupied);
            return true;
        }
        return false;
    }

    public boolean establishRoute(Route route) {
        // 检查进路条件
        if (canEstablishRoute(route)) {
            // 锁闭道岔

            for (String switchId : route.getSwitches().keySet()) {
                Switch sw = switches.get(switchId);
                if (sw != null) {
                    sw.setLocked(true);
                }
            }

            // 锁闭信号
            Signal signal = signals.get(route.getSignal());
            if (signal != null) {
                signal.setRouteLocked(true);
                signal.setAspect(Signal.SignalAspect.PROCEED);
            }

            //routes.add(route);
            return true;
        }
        return false;
    }

    public boolean canEstablishRoute(Route route) {
        // 检查道岔是否可用,一共4个道岔
        //先检查看拿到的是哪条线路
        String routeid= route.getId();
        //System.out.println(routeid);
        Signal signalP1=signals.get("P1");
        if(signalP1.getAspect()==Signal.SignalAspect.PROCEED){  //先检查P1能不能让进
            if(routeid.equals("Route1")){
                Switch sw1=switches.get("SW1");
                Switch sw3=switches.get("SW3");
                if(sw1.getPosition()==Switch.SwitchPosition.REVERSE&&sw3.getPosition()== Switch.SwitchPosition.REVERSE){
                    return true;
                }else {
                    //System.out.println("道路1不通，道岔s1和s3不对");
                    return false;
                }
            }

            if(routeid.equals("Route2")){
                for(Switch sw:switches.values()){
                    if(sw.getPosition()==Switch.SwitchPosition.REVERSE){
                        //System.out.println("道岔"+sw.getId()+"没有在正确的方向");
                        return false;
                    }
                }
                return true;
            }

            if(routeid.equals("Route3")){
                Switch sw1=switches.get("SW1");
                Switch sw2=switches.get("SW2");
                Switch sw4=switches.get("SW4");
                if(sw1.getPosition()== Switch.SwitchPosition.NORMAL&&sw2.getPosition()== Switch.SwitchPosition.REVERSE&&sw4.getPosition()==Switch.SwitchPosition.REVERSE){
                    return true;
                }else {
                    //System.out.println("Route3里面有道岔没有在正确的方位");
                    return false;
                }
            }

        }else {
            return false;
        }

        for (String switchId : route.getSwitches().keySet()) {
            Switch sw = switches.get(switchId);
            if (sw == null || sw.isBlocked() || sw.isLocked()) {
                return false;
            }
        }



        // 检查信号机是否可用
        Signal signal = signals.get(route.getSignal());
        return signal != null && !signal.isRouteLocked();
    }

    public boolean cancelRoute(String routeId) {
        Route routeToRemove = null;
        for (Route route : routes.values()) {
            if (route.getId().equals(routeId)) {
                routeToRemove = route;
                break;
            }
        }

        if (routeToRemove != null) {
            // 解锁道岔
            for (String switchId : routeToRemove.getSwitches().keySet()) {
                Switch sw = switches.get(switchId);
                if (sw != null) {
                    sw.setLocked(false);
                }
            }

            // 解锁信号
            Signal signal = signals.get(routeToRemove.getSignal());
            if (signal != null) {
                signal.setRouteLocked(false);
                signal.setAspect(Signal.SignalAspect.STOP);
            }

            routes.remove(routeToRemove);
            return true;
        }
        return false;
    }


    public Map<String, Switch> getSwitches() {
        Map<String, Switch> snapshot = new HashMap<>();
        switches.forEach((id, sw) -> {
            // 创建道岔状态的深拷贝或不可变代理
            snapshot.put(id, createSwitchSnapshot(sw));
        });
        return snapshot;
    }

    public Map<String,Train> getTrains(){
        return trains;
    }


    public Map<String, Signal> getSignals() {
//        Map<String, Signal> snapshot = new HashMap<>();
//        signals.forEach((id, sig) -> {
//            snapshot.put(id, createSignalSnapshot(sig));
//        });
        return signals;
    }

//    public Map<String,Signal> getMap(){
//
//    }

    public boolean CheckP1andP2(Map<String,Signal> signals){
        Signal s1 = signals.get("S1");
        Signal s2 = signals.get("S2");
        Signal s3 = signals.get("S3");
        Signal s4 = signals.get("S4");
        Signal s5 = signals.get("S5");
        Signal s6 = signals.get("S6");
        if(s1.getAspect() == Signal.SignalAspect.PROCEED &&
                s2.getAspect() == Signal.SignalAspect.PROCEED){
            return true;
        }

        if(s3.getAspect() == Signal.SignalAspect.PROCEED &&
                s4.getAspect() == Signal.SignalAspect.PROCEED){
            return true;
        }

        if(s5.getAspect() == Signal.SignalAspect.PROCEED &&
                s6.getAspect() == Signal.SignalAspect.PROCEED){
            return true;
        }
        return false;


    }

    public Map<String, TrackCircuit> getTrackCircuits() {
        Map<String, TrackCircuit> snapshot = new HashMap<>();
        trackCircuits.forEach((id, tc) -> {
            snapshot.put(id, createTrackCircuitSnapshot(tc));
        });
        return snapshot;
    }

    private Switch createSwitchSnapshot(Switch original) {
        Switch snapshot = new Switch(original.getId(), original.getPosition_x(), original.getPosition_y());
        snapshot.setPosition(original.getPosition());
        snapshot.setLocked(original.isLocked());
        snapshot.setBlocked(original.isBlocked());
        return snapshot;
    }

    private Signal createSignalSnapshot(Signal original) {
        Signal snapshot = new Signal(original.getId(),original.getPosition_x(),original.getPosition_y());
        snapshot.setAspect(original.getAspect());
        snapshot.setRouteLocked(original.isRouteLocked());
        return snapshot;
    }

    private TrackCircuit createTrackCircuitSnapshot(TrackCircuit original) {
        TrackCircuit snapshot = new TrackCircuit(
                original.getId(),
                original.getSectionName(),
                original.getLength(),
                original.getBroken(),
                original.getPosition_x(),
                original.getPosition_y()
        );
        snapshot.setOccupied(original.isOccupied());
        snapshot.setBroken(original.getBroken());
        // 注意：这里假设TrackCircuit的voltage字段有getter方法
        //snapshot.setVoltage(original.getVoltageStatus());
        return snapshot;
    }



}
